package com.suli.multimedia.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.suli.multimedia.entity.SalesQuantity;
import com.suli.multimedia.entity.ScenicTicket;
import com.suli.multimedia.entity.UserTicket;
import com.suli.multimedia.entity.vo.UserTicketVO;
import com.suli.multimedia.enums.TicketType;
import com.suli.multimedia.mapper.SalesQuantityMapper;
import com.suli.multimedia.mapper.ScenicTicketMapper;
import com.suli.multimedia.mapper.UserTicketMapper;
import com.suli.multimedia.service.ScenicTicketService;
import com.suli.multimedia.util.SnowFlake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author SuLi
 * @since 2022-04-02
 */
@Service
@Transactional
public class ScenicTicketServiceImpl extends ServiceImpl<ScenicTicketMapper, ScenicTicket> implements ScenicTicketService {

    @Autowired
    ScenicTicketMapper ticketMapper;
    @Autowired
    UserTicketMapper userTicketMapper;
    @Autowired
    SalesQuantityMapper quantityMapper;
    @Override
    public Map<String, Object> getTicketByPage(Long page, Long limit) {
        Page<ScenicTicket> page1=new Page<>(page,limit);
        Page<ScenicTicket> scenicTicketPage = ticketMapper.selectPage(page1, null);
        return getStringObjectMap(scenicTicketPage);
    }

    @Override
    public Map<String, Object> getTicketByPageUser(Long page, Long limit) {
        Page<ScenicTicket> page1=new Page<>(page,limit);
        QueryWrapper<ScenicTicket> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("scenic_ticket_status", TicketType.UnExpire)
                .gt("scenic_ticket_expire",new Date()).or()
                .isNull("scenic_ticket_expire");
        Page<ScenicTicket> scenicTicketPage = ticketMapper.selectPage(page1, queryWrapper);
        return getStringObjectMap(scenicTicketPage);
    }

    private Map<String, Object> getStringObjectMap(Page<ScenicTicket> scenicTicketPage) {
        List<ScenicTicket> records = scenicTicketPage.getRecords();
        long total = scenicTicketPage.getTotal();
        Map<String, Object> map=new HashMap<>();
        map.put("ticketList", records);
        map.put("total", total);
        return map;
    }

    @Override
    public boolean deleteTicketByIds(List<String> ids) {
        int i = ticketMapper.deleteBatchIds(ids);
        QueryWrapper<UserTicket> queryWrapper=new QueryWrapper<>();
        queryWrapper.in("ticket_id", ids);
        userTicketMapper.delete(queryWrapper);
        return i > 0;
    }

    @Override
    public Map<String, Object> searchTicketByEmail(String email,Long page,Long size) {
        page=(page-1)*10;
        List<UserTicketVO> userTicketVOS = userTicketMapper.searchByEmail(email,page,size);
        return getStringObjectMap(userTicketVOS);
    }

    @Override
    public Map<String, Object> searchTicketByName(String userName,Long page,Long size) {
        page=(page-1)*10;
        List<UserTicketVO> userTicketVOS = userTicketMapper.searchByName(userName,page,size);
        return getStringObjectMap(userTicketVOS);
    }

    private Map<String, Object> getStringObjectMap(List<UserTicketVO> userTicketVOS) {
        Long aLong=0L;
        if(!ObjectUtils.isEmpty(userTicketVOS)){
            QueryWrapper<UserTicket> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("user_id", userTicketVOS.get(0).getUserId());
            aLong= userTicketMapper.selectCount(queryWrapper);
        }
        Map<String, Object> map=new HashMap<>();
        map.put("userTicketList", userTicketVOS);
        map.put("total", aLong);
        return map;
    }

    @Override
    public Map<String, Object> searchTicketById(String id) {
        List<UserTicketVO> userTicketVOS = userTicketMapper.searchById(id);
        Map<String, Object> map=new HashMap<>();
        map.put("userTicket",userTicketVOS);
        return map;
    }

    @Override
    public Map<String, String> createOrder(UserTicket userTicket) {
        //返回信息
        Map<String,String> map=new HashMap<>();
        //通过乐观锁(设置version字段)进行10次循环，如果门票数为0返回，如果抢到门票返回，如果循环结束后，更新数据库失败
        //那么就返回信息让用户稍后再购票
        for (int i=10;i>0;i--){
            ScenicTicket scenicTicket = ticketMapper.selectById(userTicket.getTicketId());
            if(scenicTicket.getScenicTicketNumber()<1){
                map.put("message","门票已卖完，请等待补票");
                return map;
            }
            scenicTicket.setScenicTicketNumber(scenicTicket.getScenicTicketNumber()-1);
            scenicTicket.setScenicTicketSale(scenicTicket.getScenicTicketSale()+1);
            int update = ticketMapper.updateById(scenicTicket);
            if(update>0){
                //抢到票，现在向user_ticket表插入数据。
                long l = SnowFlake.nextId();
                String s = String.valueOf(l);
                userTicket.setId(s);
                int insert = userTicketMapper.insert(userTicket);
                if(insert>0){
                    try {
                        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
                        String format = sdf.format(new Date());
                        Date buyTime = sdf.parse(format);
                        SalesQuantity salesQuantity = quantityMapper.selectById(buyTime);
                        if(ObjectUtils.isEmpty(salesQuantity)){
                            //销量/额表更新
                            salesQuantity=new SalesQuantity();
                            salesQuantity.setBuyDate(buyTime);
                            salesQuantity.setSalesVolume(1);
                            salesQuantity.setSales(userTicket.getTicketPrice());
                            quantityMapper.insert(salesQuantity);
                        }else {
                            salesQuantity.setSalesVolume(salesQuantity.getSalesVolume()+1);
                            salesQuantity.setSales(salesQuantity.getSales().add(userTicket.getTicketPrice()));
                            quantityMapper.updateById(salesQuantity);
                        }
                        map.put("message","门票购买成功");
                        return map;
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                }
            }
        }
        map.put("message","当前购买人数过多，请稍后重试");
        return map;
    }
}
